package br.usp.ime.ingpos.web.controllers;

import java.util.ArrayList;
import java.util.List;

import org.springframework.util.StringUtils;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.Validations;
import br.usp.ime.ingpos.modelo.AreaDePesquisa;
import br.usp.ime.ingpos.modelo.Orientador;
import br.usp.ime.ingpos.modelo.dao.AreaDePesquisaDAO;
import br.usp.ime.ingpos.services.AreaDePesquisaService;
import br.usp.ime.ingpos.services.OrientadorService;
import br.usp.ime.ingpos.web.interceptors.Transactional;

@Resource
public class SecretariaController
{
    private final Result result;
    private final Validator validador;
    private final AreaDePesquisaService areaDePesquisaService;
    private final OrientadorService orientadorService;

    public SecretariaController(
        final Result result,
        final Validator validator,
        final AreaDePesquisaService areaDePesquisaService,
        final AreaDePesquisaDAO areaDeInteresseDAO,
        final OrientadorService orientadorService )
    {
        this.result = result;
        this.validador = validator;
        this.areaDePesquisaService = areaDePesquisaService;
        this.orientadorService = orientadorService;
    }

    private void carregarDadosDaPaginaAreaDePesquisa()
    {

        List<AreaDePesquisa> areasDePesquisa = new ArrayList<AreaDePesquisa>();

        areasDePesquisa = areaDePesquisaService.procurarAreasDePesquisaAtivas();

        if( ! result.included().containsKey( "acao" ) )
            result.include( "acao", "adicionar" );

        result.include( "areasDePesquisas", areasDePesquisa );
    }

    @Get
    @Path( "/secretaria/adicionaAreaDePesquisa" )
    public void cadastroAreaPesquisa()
    {
        carregarDadosDaPaginaAreaDePesquisa();
    }

    @Post
    @Path( "/secretaria/adicionaAreaDePesquisa" )
    @Transactional
    public void adicionaAreaDePesquisa(
        final AreaDePesquisa areaDePesquisa )
    {
        validador.checking( new Validations() {
            {
                that( StringUtils.hasText( areaDePesquisa.getNome() ),
                    "cadastro_area_pesquisa_nome", "cadastro_area_pesquisa_nome_erro_vazio" );

                AreaDePesquisa aux = areaDePesquisaService.procuraAreaDePesquisaPorNome( areaDePesquisa.getNome() );
                if( aux != null )
                    that( ! aux.isInseridaPelaSecretaria(), "cadastro_area_pesquisa_nome",
                        "cadastro_area_pesquisa_existente" );
            }
        } );

        if( areaDePesquisa.getAreaDePesquisaID() == null )
            result.include( "acao", "adicionar" );
        else
            result.include( "acao", "editar" );
        validador.onErrorForwardTo( getClass() ).cadastroAreaPesquisa();

        areaDePesquisa.geraDescricao();
        areaDePesquisa.setInseridaPelaSecretaria( true );
        areaDePesquisaService.inserirAreaDePesquisa( areaDePesquisa );

        result.include( "acao", "adicionar" );
        result.redirectTo( getClass() ).cadastroAreaPesquisa();

    }

    @Get
    @Path( "/secretaria/editarAreaDePesquisa/{areaDePesquisa.areaDePesquisaID}" )
    @Transactional
    public void editarAreaDePesquisa(
        final AreaDePesquisa areaDePesquisa )
    {
        result.include( "acao", "editar" );

        result.include( "areaDePesquisa",
            areaDePesquisaService.getAreaDePesquisa( areaDePesquisa.getAreaDePesquisaID() ) );

        result.redirectTo( getClass() ).cadastroAreaPesquisa();
    }

    @Get
    @Path( "/secretaria/removerAreaPesquisa/{areaDePesquisa.areaDePesquisaID}" )
    @Transactional
    public void removerAreaDePesquisa(
        final AreaDePesquisa areaDePesquisa )
    {
        areaDePesquisaService.deletarAreaDePesquisa( areaDePesquisa );
        result.redirectTo( getClass() ).cadastroAreaPesquisa();
    }

    private void carregarDadosDaPaginaOrientador()
    {
        List<Orientador> orientadores = new ArrayList<Orientador>();

        orientadores = orientadorService.procurarTodosOrientadores();

        if( ! result.included().containsKey( "acao" ) )
            result.include( "acao", "adicionar" );
        result.include( "orientadores", orientadores );
    }

    @Get
    @Path( "/secretaria/adicionaOrientador" )
    public void cadastroOrientador()
    {
        carregarDadosDaPaginaOrientador();
    }

    @Post
    @Path( "/secretaria/adicionaOrientador" )
    @Transactional
    public void adicionaOrientador(
        final Orientador orientador )
    {
        final Orientador aux = orientadorService.procurarPorId( orientador.getUsuarioID() );

        validador.checking( new Validations() {
            {
                that( StringUtils.hasText( orientador.getDadosPessoais().getNomeCompleto() ),
                    "cadastro_curriculo_nome_orientador",
                    "cadastro_orientador_interesse_nome_erro_vazio" );
                that( StringUtils.hasText( orientador.getLoginIME() ), "cadastro_orientador",
                        "erro_campo_nulo" );
                if( aux == null || ! aux.getLoginIME().equals( orientador.getLoginIME() ) ) {
                    that( ! orientadorService.isLoginIMEExistente( orientador.getLoginIME() ),
                        "cadastro_orientador", "cadastro_orientador_descricao_existente" );
                }
            }
        } );

        if( orientador.getUsuarioID() == null )
            result.include( "acao", "adicionar" );
        else
            result.include( "acao", "editar" );
        validador.onErrorForwardTo( getClass() ).cadastroOrientador();

        orientadorService.salvar( orientador );

        result.include( "acao", "adicionar" );
        result.redirectTo( getClass() ).cadastroOrientador();
    }

    @Get
    @Path( "/secretaria/editarOrientador/{orientador.usuarioID}" )
    @Transactional
    public void editarOrientador(
        final Orientador orientador )
    {
        result.include( "acao", "editar" );
        result.include( "orientador",
            orientadorService.procurarPorId( orientador.getUsuarioID() ) );
        result.redirectTo( getClass() ).cadastroOrientador();
    }

    @Get
    @Path( "/secretaria/removerOrientador/{orientador.usuarioID}" )
    @Transactional
    public void removerOrientador(
        final Orientador orientador )
    {
        orientadorService.deletarOrientador( orientador );
        result.redirectTo( getClass() ).cadastroOrientador();
    }
}
